

#ifndef __GL_MEMORY_POOL__H
#define __GL_MEMORY_POOL__H

#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <GLES3/gl32.h>
#include <map>
#include <vector>
#include "common/common.h"
#include "common/define.h"
#include "common/log.h"
#include "opengl_runtime.h"

namespace PanNN {
namespace OpenGL {
class GLMemeoryPool {
   public:
    GLMemeoryPool();
    ~GLMemeoryPool();

    GLuint GLCreateSSBO(GLsizeiptr size, void *hostData = nullptr, GLenum type = GL_SHADER_STORAGE_BUFFER,
                        GLenum usage = GL_DYNAMIC_DRAW);
    ErrorCode CopyDeviceSSBOToHost(GLuint ssboBufferID, void *hostData, GLsizeiptr size);
    ErrorCode CopyHostToDeviceSSBO(void *hostData, GLuint ssboBufferID, GLsizeiptr size);

    GLuint GLCreateTexture(int w, int h, int c, GLenum textrueFormat, GLenum target = GL_TEXTURE_3D);
    ErrorCode CopyDeviceTextureToSSBO(GLuint textureID, GLuint ssboBufferID);
    ErrorCode CopyDeviceSSBOToTexture(GLuint ssboBufferID, GLuint textureID);

    GLuint CopyHostToDeviceTexture(void *hostData, int width, int height, int channel);
    void *CopyDeviceTextureToHost(GLuint textureID);

    // key : ssboId, value : (size, type)
    std::map<GLuint, std::pair<GLsizeiptr, GLenum>> m_ssboPool;

    // key : texture, value : (textrueFormat, target)
    std::map<GLuint, std::pair<std::vector<int>, std::vector<GLenum>>> m_texturePool;
};
}  // namespace OpenGL
}  // namespace PanNN
#endif  // __GL_MEMORY_POOL__H
